initial vga mode and linear framebuffer.
When creating device model, the vga memory is allocated through
xc_domain_memory_increase_reservation(), however, when switch to use
linear framebuffer, we didn't free that memory, and re-allocate the vga
memory through set_mm_mapping(), that caused memory leak. Now it is
changed to just using qemu_malloc when create device model, and free
that memory when switch to linear framebuffer.
After unset_vram_mapping(), the old memory pointer should be
unmapped; after set_vram_mapping(), the old memory should be freed.
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
int last_hw_cursor_y_end;
int real_vram_size; /* XXX: suppress that */
CPUWriteMemoryFunc **cirrus_linear_write;
- int set_mapping;
+ unsigned long map_addr;
+ unsigned long map_end;
} CirrusVGAState;
typedef struct PCICirrusVGAState {
static void * set_vram_mapping(unsigned long addr, unsigned long end) {}
static int unset_vram_mapping(unsigned long addr, unsigned long end) {}
#endif
+extern int vga_accelerate;
/* Compute the memory access functions */
static void cirrus_update_memory_access(CirrusVGAState *s)
{
unsigned mode;
- extern int vga_accelerate;
if ((s->sr[0x17] & 0x44) == 0x44) {
goto generic_io;
mode = s->gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
- if (!s->set_mapping) {
- void * vram_pointer;
- s->set_mapping = 1;
- vram_pointer = set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
- if (!vram_pointer){
+ if ( vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end ) {
+ if (!s->map_addr) {
+ void *vram_pointer, *old_vram;
+
+ vram_pointer =
+ set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
+ if (!vram_pointer) {
fprintf(stderr, "NULL vram_pointer\n");
- } else
- {
- vga_update_vram((VGAState *)s, vram_pointer,
+ } else {
+ old_vram = vga_update_vram((VGAState *)s, vram_pointer,
VGA_RAM_SIZE);
+ qemu_free(old_vram);
}
+ s->map_addr = s->cirrus_lfb_addr;
+ s->map_end = s->cirrus_lfb_end;
}
}
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
} else {
generic_io:
if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
- if(s->set_mapping) {
+ if(s->map_addr) {
int error;
- s->set_mapping = 0;
+ void *old_vram = NULL;
+
error = unset_vram_mapping(s->cirrus_lfb_addr,
s->cirrus_lfb_end);
if (!error)
- vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
+ old_vram =
+ vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
+
+ if (old_vram)
+ munmap(old_vram, s->map_addr - s->map_end);
+ s->map_addr = s->map_end = 0;
}
}
s->cirrus_linear_io_addr);
s->cirrus_lfb_addr = addr;
s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
+
+ if ( vga_accelerate && s->map_addr &&
+ (s->cirrus_lfb_addr != s->map_addr) &&
+ (s->cirrus_lfb_end != s->map_end))
+ fprintf(logfile, "cirrus vga map change while on lfb mode\n");
+
cpu_register_physical_memory(addr + 0x1000000, 0x400000,
s->cirrus_linear_bitblt_io_addr);
}
char buf[1024];
int ret, linux_boot, initrd_size, i, nb_nics1;
PCIBus *pci_bus;
- extern void * shared_vram;
linux_boot = (kernel_filename != NULL);
if (cirrus_vga_enabled) {
if (pci_enabled) {
pci_cirrus_vga_init(pci_bus,
- ds, shared_vram, ram_size,
+ ds, NULL, ram_size,
vga_ram_size);
} else {
- isa_cirrus_vga_init(ds, shared_vram, ram_size,
+ isa_cirrus_vga_init(ds, NULL, ram_size,
vga_ram_size);
}
} else {
- vga_initialize(pci_bus, ds, shared_vram, ram_size,
+ vga_initialize(pci_bus, ds, NULL, ram_size,
vga_ram_size);
}
}
+/* when used on xen environment, the vga_ram_base is not used */
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size)
{
int i, j, v, b;
- extern void* shared_vram;
for(i = 0;i < 256; i++) {
v = 0;
/* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
* when guest write vga mem, so allocate a new one */
-#if defined(__i386__) || defined(__x86_64__)
- s->vram_ptr = shared_vram;
-#else
s->vram_ptr = qemu_malloc(vga_ram_size);
-#endif
check_sse2();
s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
if (s->vram_shadow == NULL)
return 0;
}
-int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
{
+ uint8_t *old_pointer;
+
if (s->vram_size != vga_ram_size)
{
fprintf(stderr, "No support to change vga_ram_size\n");
- return -1;
+ return NULL;
}
if ( !vga_ram_base )
if (!vga_ram_base)
{
fprintf(stderr, "reallocate error\n");
- return -1;
+ return NULL;
}
}
/* XXX lock needed? */
memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
+ old_pointer = s->vram_ptr;
s->vram_ptr = vga_ram_base;
- return 0;
+ return old_pointer;
}
/********************************************************/
unsigned int color0, unsigned int color1,
unsigned int color_xor);
-int vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
extern const uint8_t sr_mask[8];
extern const uint8_t gr_mask[16];
TextConsole *vga_console;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
int xc_handle;
-unsigned long *vgapage_array;
-unsigned long *freepage_array;
-unsigned long free_pages;
-void *vtop_table;
-unsigned long toptab;
-unsigned long vgaram_pages;
/***********************************************************/
/* x86 ISA bus support */
#include <xg_private.h>
-#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-
-#ifdef __i386__
-#define _LEVEL_3_ 0
-#else
-#define _LEVEL_3_ 1
-#endif
-
-#if _LEVEL_3_
-#define L3_PROT (_PAGE_PRESENT)
-#define L1_PAGETABLE_ENTRIES 512
-#else
-#define L1_PAGETABLE_ENTRIES 1024
-#endif
-
-inline int
-get_vl2_table(unsigned long count, unsigned long start)
-{
-#if _LEVEL_3_
- return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
-#else
- return 0;
-#endif
-}
-
/* FIXME Flush the shadow page */
int unset_mm_mapping(int xc_handle,
uint32_t domid,
int serial_device_index;
char qemu_dm_logfilename[64];
const char *loadvm = NULL;
- unsigned long nr_pages, extra_pages, ram_pages, *page_array;
- xc_dominfo_t info;
+ unsigned long nr_pages, *page_array;
extern void *shared_page;
- extern void *shared_vram;
#if !defined(CONFIG_SOFTMMU)
/* we never want that malloc() uses mmap() */
/* init the memory */
phys_ram_size = ram_size + vga_ram_size + bios_size;
- ram_pages = ram_size/PAGE_SIZE;
-#if defined(__i386__) || defined(__x86_64__)
- vgaram_pages = (vga_ram_size -1) / PAGE_SIZE + 1;
- free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
- extra_pages = vgaram_pages + free_pages;
-#else
- /* Test vga acceleration later */
- extra_pages = 0;
-#endif
+ nr_pages = ram_size/PAGE_SIZE;
xc_handle = xc_interface_open();
- xc_domain_getinfo(xc_handle, domid, 1, &info);
-
- nr_pages = info.nr_pages + extra_pages;
-
- if ( xc_domain_setmaxmem(xc_handle, domid,
- (nr_pages) * PAGE_SIZE/1024 ) != 0)
- {
- fprintf(logfile, "set maxmem returned error %d\n", errno);
- exit(-1);
- }
-
if ( (page_array = (unsigned long *)
malloc(nr_pages * sizeof(unsigned long))) == NULL)
{
exit(-1);
}
- if (xc_domain_memory_increase_reservation(xc_handle, domid,
- extra_pages , 0, 0, NULL) != 0)
- {
- fprintf(logfile, "increase reservation returned error %d\n", errno);
- exit(-1);
- }
-
#if defined(__i386__) || defined(__x86_64__)
if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
{
fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
exit(-1);
}
-
if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE,
page_array,
- ram_pages - 1)) == 0 )
+ nr_pages - 1)) == 0 )
{
fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
exit(-1);
shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
PROT_READ|PROT_WRITE,
- page_array[ram_pages - 1]);
-
- vgapage_array = &page_array[nr_pages - vgaram_pages];
-
- if ( (shared_vram = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- vgapage_array,
- vgaram_pages)) == 0)
- {
- fprintf(logfile,
- "xc_map_foreign_batch vgaram returned error %d\n", errno);
- exit(-1);
- }
-
- memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
- toptab = page_array[ram_pages] << PAGE_SHIFT;
-
- vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- page_array[ram_pages]);
+ page_array[nr_pages - 1]);
- freepage_array = &page_array[nr_pages - extra_pages];
#elif defined(__ia64__)
- if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, ram_pages)
- != ram_pages )
+ if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, nr_pages)
+ != nr_pages)
{
fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
exit(-1);
if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE,
page_array,
- ram_pages)) == 0 )
+ nr_pages)) == 0 )
{
fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
exit(-1);
if ( xc_ia64_get_pfn_list(xc_handle, domid,
page_array,
- ram_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
+ nr_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
{
fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
exit(-1);